/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.yunhoo.sys.login;

import com.ibatis.dao.client.DaoManager;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.yunhoo.base.bean.OrganizationBean;
import com.yunhoo.base.model.Department;
import com.yunhoo.base.model.Organization;
import com.yunhoo.base.model.Person;
import com.yunhoo.sys.db.config.DaoConfig;
import com.yunhoo.base.db.dao.DepartmentDao;
import com.yunhoo.base.db.dao.OrganizationDao;
import com.yunhoo.base.db.dao.PersonDao;
import com.yunhoo.govProcure.bean.BuildAssetBean;
import com.yunhoo.sys.db.util.IbatisTemplate;
import com.yunhoo.sys.navigation.MenuBean;
import com.yunhoo.sys.util.common.FacesUtils;
import com.yunhoo.sys.util.common.SysConfigMap;
import com.yunhoo.sys.util.common.ToolKit;
import com.yunhoo.sys.util.tree.MyTreeNodeImpl;
import com.yunhoo.sys.util.tree.TreeRule;
import com.yunhoo.sys.util.tree.TreeUtil;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.NavigationHandler;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.richfaces.event.TreeSelectionChangeEvent;
import org.richfaces.model.TreeNode;

@ManagedBean(name = "loginBean")
@SessionScoped
public class LoginBean implements Serializable {

    private static final DaoManager daom = DaoConfig.getDaoManager();
    private static final OrganizationDao orgDao = (OrganizationDao) daom.getDao(OrganizationDao.class);
    private static final DepartmentDao deptDao = (DepartmentDao) daom.getDao(DepartmentDao.class);
    private static final PersonDao perDao = (PersonDao) daom.getDao(PersonDao.class);
    //
    private Integer iyear = null;
    private Organization org = new Organization();
    private Department dept = new Department();
    private Person per = new Person();
    private Date loginDate = new Date();
    //
    private TreeNode orgTree = null;
    private TreeNode deptTree = null;
    private List<SelectItem> perli = null;

    public LoginBean() {
        Map<String, String> map = initDefaultValueMap();
        org.setCode(map.get("orgCode"));
        iyear = Integer.parseInt(map.get("iyear"));
        // test();
    }

    private Map<String, String> initDefaultValueMap() {
        return SysConfigMap.getSysConfigMap("defaultValue");
    }

    private Map<String, String> initDefaultValueMap_() {
        SqlMapClient client = IbatisTemplate.getSqlMapClient();
        Map<String, String> map = null;
        try {
            client.startTransaction();
            map = client.queryForMap("defaultValue.queryMapDefaultValue", null, "key", "value");
            client.commitTransaction();
        } catch (SQLException ex) {
            try {
                client.endTransaction();
            } catch (SQLException ex1) {
                Logger.getLogger(LoginBean.class.getName()).log(Level.SEVERE, null, ex1);
            }
            Logger.getLogger(BuildAssetBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        return map;
    }

    private void test() {
        iyear = 2013;
        org = new Organization();
        org.setCode("10201");
        org.setName("信访局");
        dept = new Department();
        dept.setCode("01");
        dept.setName("办公室");
        per = new Person();
        per.setCpsn_number("01004");
        per.setCpsn_name("陈颙");
        per.setPwd("1");
    }

    public void login() {
        Person ps = null;
        try {
            per.setOrgCode(org.getCode());
            per.setIyear(iyear);
            ps = perDao.queryByIdAndPwd(per);
        } catch (SQLException ex) {
            Logger.getLogger(LoginBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (ps == null) {
            ToolKit.msgs_err("密码错误!请重新输入!");
            //return "login";
            return;
        }
        per = ps;

        //将用户id 放入HttpSession
        HttpSession session = FacesUtils.getSession();
        HashMap<String, Object> sysParam = (HashMap<String, Object>) session.getAttribute("sysParam");
        if (sysParam == null) {
            sysParam = new HashMap<String, Object>();
            session.setAttribute("sysParam", sysParam);
        }
        sysParam.put("userId", ps.getCpsn_number().trim());

        //处理重复登录 --> 注销以前登录的session
        loginRepeat(ps.getCpsn_number().trim(), session);

        //保存登录信息进 HttpSession
        saveLoginInfoInSession();

        //将session中 bean 设为空
        initSessionValue();

        initMenuBeanWelcomePage();

        //return "main";
        FacesContext fc = FacesContext.getCurrentInstance();
        NavigationHandler ndl = fc.getApplication().getNavigationHandler();
        ndl.handleNavigation(fc, null, "/main.xhtml?faces-redirect=true");
    }

    private void saveLoginInfoInSession() {
        ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
        HttpServletResponse response = (HttpServletResponse) extContext.getResponse();
        response.setCharacterEncoding("UTF-8");
        Map sessionMap = extContext.getSessionMap();

        sessionMap.put("loginInfo", new LoginInfo(iyear, org, dept, per, loginDate));
    }

    public static void loginRepeat(String curUserId, HttpSession curSession) {
        try {
            HttpSession httpSession = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
            ServletContext application = httpSession.getServletContext();

            HashSet<HttpSession> sessions = (HashSet) application.getAttribute("sessions");
            if (sessions == null) return;

            //放 重复登录的session（不包括当前用户）
            HashSet<HttpSession> sesion_repeat = new HashSet<HttpSession>();

            //当前sessionId
            String curSessionId = curSession.getId();

            for (HttpSession sn : sessions) {

                if (curSessionId.equals(sn.getId())) continue;//非当前session

                HashMap<String, Object> sysParam = (HashMap<String, Object>) sn.getAttribute("sysParam");
                if (sysParam == null) continue;//sysParam为null，用户未登录

                String userId = (String) sysParam.get("userId");

                if (curUserId.equals(userId)) {

                    //sysParam.put("invalidate", "1");//重复登录，打上标记
                    //sn.invalidate();//注销
                    sesion_repeat.add(sn);//将重复的session 放入集合，后面集中注销
                }
            }

            //
            for (HttpSession sn : sesion_repeat) {
                sn.invalidate();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initMenuBeanWelcomePage() {
        MenuBean menuBean = (MenuBean) FacesUtils.getManagedBean("sysmenu");
        menuBean.initSelectedPage();
    }

    private void initSessionValue() {
        Map sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
        sessionMap.put("loan", null);
        sessionMap.put("abroadGroupBean", null);
        sessionMap.put("proof", null);
        sessionMap.put("expinput", null);
        sessionMap.put("payApplication", null);
        sessionMap.put("trainput", null);
    }

    public void yearChange() {
        if (iyear != null && org.getCode() != null) {
            loadDeptTree();
        }
    }

    public void orgChange(TreeSelectionChangeEvent event) {
        Organization node = (Organization) TreeUtil.listener(event);
        if (node.getIsEnd() == 1) {
            org = node;
            if (iyear != null) {
                loadDeptTree();
            }
        }
    }

    public void deptChange(TreeSelectionChangeEvent event) {
        Department node = (Department) TreeUtil.listener(event);
        if (node.getIsEnd() == 1) {
            dept = node;
            loadPerli();
        }
    }

    private void loadOrgTree() {
        orgTree = new MyTreeNodeImpl();
        List<Organization> li = null;
        try {
            li = orgDao.queryAll();
        } catch (SQLException ex) {
            Logger.getLogger(OrganizationBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (null == li) {
            System.out.println("org li is null !");
            return;
        }
        TreeUtil.addNode(li, orgTree, TreeRule.getOrganizationTreeRule());
    }

    private void loadDeptTree() {
        deptTree = new MyTreeNodeImpl();
        if (org.getCode() == null || iyear == null) {
            return;
        }
        List<Department> li = null;
        try {
            Department param = new Department();
            param.setOrgCode(org.getCode());
            param.setIyear(iyear);
            li = deptDao.queryListByOrgAndYear(param);
        } catch (SQLException ex) {
            Logger.getLogger(OrganizationBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        TreeUtil.addNode(li, deptTree, TreeRule.getDepartmentTreeRule());
    }

    private void loadPerli() {
        perli = new ArrayList<SelectItem>();
        if (org.getCode() == null || iyear == null) {
            return;
        }
        List<Person> templi = null;
        try {
            Person param = new Person();
            param.setOrgCode(org.getCode());
            param.setIyear(iyear);
            param.setDeptCode(dept.getCode());
            templi = perDao.queryListByDept(param);
        } catch (SQLException ex) {
            Logger.getLogger(LoginBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (templi != null) {
            for (Person p : templi) {
                perli.add(new SelectItem(p.getCpsn_number(), p.getCpsn_name()));
            }
        }
    }

    public TreeNode getOrgTree() {
        if (orgTree == null) {
            loadOrgTree();
        }
        return orgTree;
    }

    public TreeNode getDeptTree() {
        if (deptTree == null) {
            loadDeptTree();
        }
        return deptTree;
    }

    public Integer getIyear() {
        return iyear;
    }

    public void setIyear(Integer iyear) {
        this.iyear = iyear;
    }

    public Organization getOrg() {
        return org;
    }

    public void setOrg(Organization org) {
        this.org = org;
    }

    public Department getDept() {
        return dept;
    }

    public void setDept(Department dept) {
        this.dept = dept;
    }

    public Person getPer() {
        return per;
    }

    public void setPer(Person per) {
        this.per = per;
    }

    public Date getLoginDate() {
        return loginDate;
    }

    public void setLoginDate(Date loginDate) {
        this.loginDate = loginDate;
    }

    public List<SelectItem> getPerli() {
        return perli;
    }

    public void setPerli(List<SelectItem> perli) {
        this.perli = perli;
    }
}
